perm filename TELLEM[S,AIL]7 blob sn#058522 filedate 1973-08-19 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00025 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00003 00002	
C00004 00003	INTRODUCTION
C00005 00004	OPTIONS
C00009 00005	PARTS LIST (see appendix II for expanded explanations)
C00014 00006	REMOVING THE FILES FROM THE DISTRIBUTION TAPE
C00015 00007	INSTALLING AN INITIAL SAIL SYSTEM
C00019 00008	MODIFYING THE COMPILER
C00023 00009	
C00028 00010	NON-SHARED, NO LIBRARY RUNTIME ROUTINES {BIGRUN}
C00030 00011	RUN-TIME LIBRARY {LIB}
C00035 00012	SHARED SECOND SEGMENT EXECS {TWOSEG}
C00042 00013	OPERATING WITH SHARED SEGMENTS {TWOSEG}
C00046 00014	APPENDIX I -- SAILMAKER's CHECKLIST
C00049 00015	
C00052 00016	APPENDIX II -- FILE DESCRIPTIONS
C00057 00017	
C00063 00018	APPENDIX III -- REFERENCES TO OTHER USEFUL DOCUMENTATION
C00065 00019	APPENDIX IV -- THE PARSE TABLES (HEL) AND PRODUCTION COMPILER (PTRAN)
C00070 00020	
C00074 00021	
C00081 00022	
C00084 00023	
C00089 00024	APPENDIX V -- DDT AND OTHER MODIFIED DEC SOFTWARE
C00096 00025	APPENDIX VI -- ADDITIONAL SUPPORT SOFTWARE -- SCISS, MAKTAB
C00108 ENDMK
C⊗;






















	SAILMAKERS GUIDE










				Bob Sproull
				October 1970
				Revised May 1971 by D. Swinehart
				Revised Sept 1971 by D. Swinehart
				Revised Jan 1973 by D. Swinehart and J. Low
				Revised May 1973 by R. Taylor
				Revised June 1973 by H. Samet 
INTRODUCTION

This document describes the various parts of the SAIL system, and how
they   might  be  combined  to  form  many  optional  manifestations.
Hopefully  not  only  the  methods  for  installing  SAIL,  but   the
motivations behind them will be explained.

The first sections are somewhat wordy, and describe in detail what is
going on.  Later sections may be used as checklists in performing the
actual    installation.    Appendices    follow,    explaining   less
commonly-needed facts.
OPTIONS

You will probably not want a system with all  the  available  options
and configurations (especially since some are mutually exclusive). So
that you may readily ignore explanations of features you don't  want,
sections   which  represent  optional  things  are  labelled  in  the
following manner:

LEAP -- this section is of interest only if you want a runtime system
    with LEAP and PROCESS features. (The compiler always includes the
    LEAP and PROCESS features)
    It is advised that LEAP always be included as we have  maintained
    the system with the belief that LEAP will be around.
NOLEAP -- this section of interest only if you want one without LEAP.

TWOSEG--this section describes  the  sharable  (2d  segment)  runtime
     routines  configuration. 
NOTWOSEG -- of interest only in non-sharableconfigs etc.

LIB  --  describes the process for creating the LIBSAn library. 
NOLIB-- etc.

REENT -- describes the process for creating re-entrant SAIL programs,
     such  that not only the runtimes, but the entire user program is
     sharable; and the library (HLBSAn) that goes with such programs.

BIGRUN, NOBIGRUN -- describes the process  for  creating  RUNTIM.REL,
all runtimes, non-sharable.

GLOB, NOGLOB & GLOC, NOGLOC & EXPO-NOEXPO -- These refer to differences
between SAIL as it exists at Stanford & as it exists elsewhere.  These
differences include a slightly different interface to the (non-DEC-standard)
Stanford operating system, and to the Stanford "global model", which
requires special UUOs found only at Stanford.  In times past, the export
sources  were modified to omit Stanford-only features.  In accordance
with a new file maintainence policy, they are being left in.  They certainly
will not work on a regular DEC or TENEX system, and we make no promises,
either implicit or explicit, to those who feel like monkeying around with
them.  To avoid problems, leave the switch EXPORT set to 1 in file HEAD
(and don't go changing GLOCSW or GLOBSW).

When these tags appear, they will be between braces ({}) in the text.

PARTS LIST (see appendix II for expanded explanations)

A  Files needed to get initial compiler and operating system going
   FILES (list of files in order on tape)
   TELLEM (this listing)
   SAIL.REL
   DDT.REL (currently can't use any configuration of DEC's DDT)
   LIBSAn.REL (n, a digit.Library of runtime routines for transfer to SYS:)
   BKTBL.BKT (needs to be on SYS when STDBRK is called)
   2OPS2.OPS (START_CODE opcode table, created by compiling and
		running MAKTAB)
   PROCES.DEF (a collection of SAIL macros for use with processes)

B. Source files for SAIL compiler and execs(runtimes)
   HEAD
   FILSPC

E. Files to build parser tables (FAIL files for inclusion in SAIL)
   FOO2
   HEL
   PROD.QQQ (output of PTRAN, input is HEL)

F. Source files for SAIL compiler
   SAIL
   PARSE
   (HEL, FOO2 as comments)
   PROD (output of PTRAN, input is HEL)
   RESTAB (output of RTRAN, input is PROD and FOO2)
   SYM
   GEN
   ARRAY
   EXPRS
   STATS
   LEAP
   TOTAL
   PROCSS 
   COMSER

G. Source files for Execs
   GOGOL
   STRSER
   IOSER
   ARYSER
   UP {TWOSEG}
   LOW {TWOSEG}
   TAILOR {TWOSEG}
   LEPRUN {LEAP}
   WRDGET {LEAP}
   NWORLD {LEAP}
   ORDER {LIB}

H. Required software support, if any modifications are to be made
   FAIL.REL (a one-pass assembler)
   PTRAN.SAI (creates FAIL-readable parser tables from HEL)
   RTRAN.SAI (creates FAIL-readable symbol table (reserved wds) from FOO2)
    (above previously HYSS and HYRS, respectively)
   SCNCMD.SAI (gets REQUIRED as a source file by PTRAN and RTRAN)
   WNTSLS.SAI (gets REQUIRED as a source file by PTRAN and RTRAN)
   MAKTAB.SAI (creates 2OPS2.OPS)

I. Other useful files
   PROFIL.SAI -- This program lists the .KNT file and .LST file, giving a
   nice frequency profile of statement execution (See /K Switch in manual)
   LOADER.MAC (our slightly modified version 52)
   FAIL.FAI
   DDT.FAI (our slightly modified version -- block structure)
   CREF.MAC (modified for block structure)
   SCISS.SAI (makes a a library, two-segment HLBSAn {REENT} or one-segment
	LIBSAn. Uses the file ORDER as input with other exec sources)
   FAIL.PMP -- FAIL assembler manual
   SAIL.KVL-- SAIL manual -- restoration of these last two to DSK should
	      be inhibited if disk storage is scarce -- about 100K worth.

K. Some additional files of marginal usefulness.  They are either documents,
   or programs whose only documentation is self-contained, if at all.  You
   can take a look at them if you want to.  They are mostly SAIL programs
   and their manuals.
   ARRSER,EXTEND,SRTSER,SYMSER,LP4MAT,LPDUMP,LPREAD,
   CONST.HDR,CONST.SAI,MUNGE.SAI,IOMODS.SAI
   ABBREV.SAI,MACROS.SAI,LEPAUX.SAI,LEPAUX.HDR
   SPACE.HDR,SPACE.FAI,IOMOD.HDR,IOMOD.SAI

REMOVING THE FILES FROM THE DISTRIBUTION TAPE

A.DECTAPE

This  presents  no  problem. The files are stored on several DECtapes
with  the  directories  plainly  listed thereon. They are  stored  in
standard PDP-10 DECTAPE format.

B. Mag Tape, 7 track only

Use FAILSAFE

C. Subsequent updates to the SAIL system will  probably  be  provided
via SOUP update files, so KEEP THESE ORIGINALS, INTACT!!
INSTALLING AN INITIAL SAIL SYSTEM

The file SAIL.REL should run on any  standard  DEC  10/50  system  of
recent  (year  or  two)  vintage.  Load it with the DDT.REL provided,
and the library (LIBSAn), with the /B loader switch, using version 54
or later of the LOADER, with SAILSW and FAILSW turned on, and save it
as SAIL.SAV (one segment) somewhere. Later descriptions will indicate
a method  for creating a version without DDT.

The  file  LIBSAn.REL  is  the  library  which  is  REQUIREd  by  all
SAIL-compiled programs.  It uses a  recently-installed  LOADER  block
type  to  cause the automatic search.  The LOADER will look on device
SYS for this file, and will not really let you go  on  until  such  a
file  is  put  there.   The  version  of  LIBSAn  supplied  should be
sufficient in all important  details  (at  least  till  you  get  the
bootstrapping done).

If  you have installed SAIL on your SYS device, CCL may be changed to
include SAIL as a standard processor by including the line

	X	SAIL,SAI,SAIL

in  the  PROCESS  macro  in  COMPIL.MAC  (DEC  program). You may also 
include  "FAIL,FAI,FAIL"  if  you  want  to  promote  use of the FAIL
assembler.

To  complete a SAIL system (if you're not going to investigate any of
the other, better options or make any  changes),  transfer  2OPS2.OPS
and  BKTBL.BKT  to  SYS.   Always  load  SAIL-compiled  programs with
version  54  of  the  LOADER  or  later (LOADER 52 may be used if the
compiler is reassembled with the  LOADVR  switch  in  file  SAIL  set
to =52), with SAILSW and FAILSW  turned  on (or  ours, which  has its
points), and always use our DDT (at least until we can get together
with DEC on it).

There is one additional thing you can do if you want  to  --  install
the  LOADER  provided  with  SAIL.  This LOADER uses the /Y switch to
make shared-segment  loading  more  convenient  (See  Operating  with
shared  segments, below. In addition, it automatically invokes /B and
/K to cut core to reasonable sizes after loading.  It is by no  means
necessary to use our LOADER,  though. If  our  LOADER  is  used,  the 
LOADVR switch in file SAIL must be set to =52 and SAIL reassembled.

MODIFYING THE COMPILER

The comments which accompany the source  files are  fairly  extensive.
This,  however,  is  about  the  only  assistance  you  will  get  in
understanding the compiler,  except  for  the  Parser  discussion  in
appendix  IV.  Therefore,  this  section  is  not  intended to aid in
anything but the actual mechanics (assembly, etc.) of modifying SAIL.

A. If you have only modified FAIL code, the process is fairly simple:

  1. One Segment Compiler

  This  command  string  should  be  typed  to  FAIL  (or  the
  equivalent formulation given via CCL:

  SAIL←HEAD,SAIL,PARSE,HEL,FOO2,PROD,RESTAB,SYM,GEN,ARRAY,EXPRS,
	STATS,LEAP,TOTAL,COMSER

  SAIL.REL will be created.  This version is tailored for  slimness,
  and is not intended to be loaded with DDT.  It should be loaded
  with the LIBSAn library.A typical LOADER command string is
	
  SAIL,/LLIBSAn

  2. One Segment Compiler, tailored for debugging.

  This version should  (sort  of  must)  be  loaded  with  DDT.   It
  contains  code  for  the  /nM options described in the SAIL manual
  (and slightly better in the file PARSE just ahead of the code that
  does  it).  With  this  compiler  it  is much easier to track down
  elusive "line 99500, page 47" bugs.

  The command string is the same, except that FTDEBUG should be made
  1  instead  of 0 (never -1, 3, or anything but 0 or 1!!!!!) in the
  file SAIL (or insert a file with FTDEBUG←←1 in it ahead of SAIL).

  This is the version which was sent to you as SAIL.REL.
  If you do not use our LOADER remember to include the /B switch
  in your LOADER string or you will get the wonderful warning:

	"YOUR SYMBOLS ABOUT TO BE OBLITERATED"

  everytime you run the compiler.

  3. Two Segment Compiler, no debugging {TWOSEG}

  Set FTDEBUG=0 in HEAD, and use the above command string,
  Load without DDT,  but  as  if  it  were  a  two-segment
  SAIL-compiled  program  (see Two Segment operation, below).   Save
  in ONE segment, always (as with any SAIL-compiled job, see below).
  When it runs, it will pick up the shared stuff.

  4.  Two  segments,  debugging  mode  Same  as  version 3, but make
  FTDEBUG←←1, load with DDT.



B. Changes to HEL (parse table) or FOO2 (built-in procedures)

  If for any reason you change either of these files, more work  has
  to be done:


  NOTE -- PTRAN and RTRAN replace HYRS and HYSS, resp.

  1.  PTRAN  -- Production Translator (see Appendix IV) This program
  takes the pseudo Floyd-Evans productions found in  file  HEL  (or
  any  other),  and  converts  it  to  FAIL  assembly  language data
  statements which define interpretation tables for  the  parser  of
  SAIL.   In  addition,  it issues an auxilliary file containing the
  names of  the  reserved  words,  for  use  in  the  RTRAN  program
  described below.

  Compile PTRAN.SAI with your slightly used copy of  SAIL,  load  it
  and  run  it.   It  will  respond  with a `*', to which you should
  counter:    PROD←HEL<cr>.   When another  `*'  appears,  PROD  and
  PROD.QQQ  have  been  created.   PROD  is the parse table (HEL  is
  included only as a comment in the assembly  above,  as  is  FOO2).
  PROD.QQQ is the list of reserved words for RTRAN.

  2. RTRAN -- Reserved Word Translator

  This  program  issues  FAIL  source code which defines the initial
  configuration of the SAIL internal symbol table, for the  reserved
  words  like  BEGIN  and  END,  and for the execution routines like
  INPUT, BREAKSET, etc.  Input for the  reserved  words  comes  from
  PROD.QQQ  via  PTRAN.   Input  for the executions is from the file
  FOO2.  Appendix IV describes the formats of these files in detail.
  The  command  string  is:    RESTAB←PROD,FOO2<cr>.  The  resultant
  RESTAB is the initial symbol table, expressed in FAIL.

  Now proceed as given in part A.

  PTRAN  will  read  commands from nnnPTR.TMP if started in CCL mode.
  RTRAN will read from nnnRTR.TMP. Make what you like of that.


C. Some particularly interesting conditional assembly switches

  FTDEBUG -- 1 for debug/mode, 0 for non-debug mode, as above.

  LEAPSW  {LEAP}  -- on for LEAP features in runtimes (standard), off
  otherwise.

  RENSW -- usually 1 -- on if compiler is to be capable of generating
  re-entrant (two-segment) code.  To get it to do that, use /H in the
  command string.  Such a file will REQUIRE the HLBSAn library, each
  file of which has been HISEGed (see below).  Most of the program
  can thus be shared, if the program has reached CUSP status.

  SIXSW -- turn this on if you use sixbit project-programmer numbers.
  Otherwise, SAIL assumes octal ones.  Examine all SIXSW-dependent
  code if you use something else entirely, and make changes.

  TMPCSW -- turn this off if your system does not support the TEMPCOR
  UUO.

  LOADVR -- the decimal value of the loader version to be used;
  =52 or >=52, typically - loader block type problems.

NON-SHARED, NO LIBRARY RUNTIME ROUTINES {BIGRUN}

The  files  GOGOL,  STRSER, IOSER, ARYSER, NWORLD, LEPRUN and WRDGET,
along  with  the macro and accumulator  definition  file  HEAD,  were
historically assembled in the order

HEAD,GOGOL,STRSER,IOSER,ARYSER,NWORLD,LEPRUN,WRDGET

to  create  a  file RUNTIM.REL which contained the storage allocator,
the initializer, the string garbage collector, and all the  execution
routines  (INPUT, BREAKSET, concatenation, CVS, LEAP, etc.).

This  method  may  still  be  used.   Simply assemble the files given
above, in  the  order  specified.  Specify   RUNTIM.REL, or  anything
else, for that  matter,  as  the  binary  file.   This  file,  loaded
with a SAIL-compiled program, will provide all the support necessary.
Unfortunately, it is about 9.5K long.


RUN-TIME LIBRARY {LIB}

We  found  that  out.   However,  the  obvious  solution to the large
execution package revealed some drawbacks.  We  wanted  to  create  a
library  for  SAIL  in  the  manner of the FORTRAN library.  However,
given the DEC  library  file  conventions,  each  separately-loadable
entry  would  have  to be assembled separately.  This was not so bad,
but it would mean fragmenting GOGOL  and  friends  into  many  parts,
making the creation of RUNTIM.REL or the shared segment version hard.
It was crucial  that  there  not  be  multiple  copies  of  the  same
routines, because maintenance of one set is hard enough.......

The  current  solution  to the problem is the program SCISS.SAI, some
special macro constructs in GOGOL and friends, and a lot of luck.

SCISS operates in two passes, with a pass of FAIL  between.   On  the
first  pass, it extracts from HEAD and GOGOL some common code used by
all library entries (making  HDRFIL.FAI,  or  some  such).   Then  it
writes   one  FAIL  source  file  for  each  desired  library  entry,
extracting  its  code  from  the  file GOGOL, STRSER, or IOSER etc.in
which  it appears  (removing  comments  and blank lines), naming each
after its library entry.  In addition, it writes a command file
(CCL  file) to FAIL, then chains to FAIL. The file ORDER contains the
correspondence  between  library entries and the source files as well
as "n" the version of the library.

FAIL  assembles  all  the  little FAIL files, each preceded by HDRFIL,
into little .REL files, chaining back to SCISS, this time in CCL mode,
thus  indicating  pass 2.  On pass 2, SCISS copies all the .REL files
into LIBSAn.REL, removing local symbols and cleaning things up.   All
the  FAIL  and  .REL  files, along with the HDRFIL and CCL files, are
deleted if desired.

Here we will only discuss the STANDARD case.  The procedure is:


Read  into  GOGOL,  looking  for the COMPILE macro, the ENDCOM macro.
Also  look  at the file ORDER.  These should give you an idea of what
is going on inside to give SCISS a hand.

Compile  and load  SCISS.SAI, and save it as SCISS.SAV on the area on
which you intend to run it.

Run  SCISS.  It  will  read the file ORDER (from the current area) as
input. When  it  asks   "STANDARD?  ",   answer   "Y<cr>".   It  will
chatter for some time about what it intends to do, then about what it
is doing. Thereafter, FAIL will be invoked to compile all the  little
files.  Finally  SCISS  will  return  with  "STANDARD? ".  Answer Yes
again.  It will drone on some more about the files it is deleting and
copying.   Finally  it  will  report  that  LIBSAn.REL exists for the
using.

{REENT}
Use  an  option  of  SCISS (see appendix VI) to  get the high segment
library (HLBSAn). Programs compiled with /H will use HLBSAn -- others
will  use  the  shared  segment  (see {TWOSEG} below) or LIBSAn.  You
should  create  only  a  LIBSAn  if you don't make a /H-type compiler 
(RENSW off in SAIL) when you assemble it.

If anything goes wrong,  you  will  probably  profit  from  the  more
complete discussion of SCISS in appendix VI.
SHARED SECOND SEGMENT EXECS {TWOSEG}

This option represents the latest step  in  the  evolution  of  these
things. In this version, we are back to the 9.5K runtime package, but
this time it occupies the (entire) second segment of  any  number  of
jobs.   Linkage to routines in this segment is accomplished at LOADER
time by loading as the FIRST THING a file containing  the  name  of a
particular upper segment, as well as symbol names and  locations  for
that upper segment's routines.  In addition, this file  contains some
impure  data  for the SAIL job, along with the UUO trap locations and
the  code  necessary  to  attach via GETSEG to the specified segment.
In this way the upper and lower files are keyed to each other, and as
long as standard naming conventions are followed, an  old  .SAV file,
when run, will never link to a new segment with unmatching addresses.
A  transfer  vector in the upper segment,  through which all calls to
runtime routines go, also minimizes this possibility of dissynchroni-
zation.

To  create one of these clever beasts, first look at the file FILSPC.
It contains default values  for  this  lower  segment  name  (SAILOW,
typically),  the current upper segment name (SAISGn, n a digit) which
will be unique to this particular manifestation (or at  least  should
change  when  the transfer vector changes), and some parameters which
are probably meaningless in your installation, and should be left  as
they  are.   In  addition, the device (DSK or SYS) and PPN pair where
the  segment file will  be  found  is  also  defined  therein.   Thus
SAISGn.SHR is one file which need not reside on SYS.

Once you are satisfied that FILSPC is OK (modification should include
noting on page 2 the date, the version number if you must,  and  what
glorious  changes  warrant  the new version), Use FAIL on the command
string:

LOWER←HEAD,FILSPC,LOW,GOGOL,STRSER,IOSER,ARYSER,NWORLD

LOWER.REL will be a binary file containing the desired upper  segment
name and location  (for  use  by  the GETSEG routine), and the lower-
segment  initialization  and  impure code, selected from GOGOL by the
conditional assembly in LOW.

Now use FAIL to assemble:

TAILOR←HEAD,FILSPC,TAILOR (or the CCL equivalent, of course).
 

TAILOR.REL contains the upper segment name and location,  along  with
the other useless parameters from FILSPC, this time in core locations
rather  than as assembly constants.  This could have been included in
the next assembly, but wasn't so  that  the names  and  other  things
could  be changed without re-assembling the body of the segment code.

The last assembly is:

UPPER←HEAD,UP,ORDER,GOGOL,STRSER,IOSER,ARYSER,NWORLD,LEPRUN,WRDGET

UPPER.REL contains, after some initial messing around, code PHASEd to
400000 and succeeding locations, so that when it  is  fetched  as  an
upper  segment, it will be able to run there.  The trick is to get it
written out such that this can be done.  Some of that  which  follows
may  look  ridiculous and overly complex to some of you, but remember
that the code, with modifications, must also  be  used  at  Stanford,
where things are done that way.

First load TAILOR and UPPER together.  This tells UPPER what its name
will be.  There is code in UP, before the phase,  and  to  which  the
starting address of the UPPER assembly refers, which will now perform
some contortions:

Start the resultant core image.  The code in UP will first write  out
pure segment code onto the file SAISGn.SHR ON THE  CURRENT  DIRECTORY
AREA,  notwithstanding  its  ultimate destination.  Then it will copy
LOWER.REL to SAILOW.REL  (or  whatever  FILSPC  says),  imbedding  in
SAILOW , in LOADER INTERNAL symbol format, the symbol names and upper
segment addresses for all the runtime routines and other  data  which
SAIL  programs must reference.  These symbols are taken directly from
the current core image's symbol table, which contains all the symbols
and their values, because the UPPER file was loaded with it.

SAILOW.REL   and  SAISGn.SHR  should  be  copied  to  their  intended
destinations (usually SYS).
OPERATING WITH SHARED SEGMENTS {TWOSEG}

To  create  a  core  image  which will use the shared SAISGn segment,
whether it be the compiler (see above sections)  or  a  SAIL-compiled
program,  simply  load it with the most recent SAILOW.REL as the VERY
FIRST THING (locations 140 cc.) in the core image.  SAISGn KNOWS that
certain  data  in SAILOW will be at these locations. SAILOW, in turn,
"knows", via the implanted symbols, where the  runtime  routines  for
the  SAISGn  keyed  to  it are.  Therefore, all references to runtime
routines in the files loaded after SAILOW will be  properly  resolved
to upper segment addresses.

After  loading  SAILOW, DDT can be loaded if desired, followed by any
SAIL-compiled or FAIL/MACRO/FORTRAN-processed files.   When  the  job
(which  should  have  a  SAIL  main program) is started, it will do a
GETSEG on the appropriate SAISGn.SHR, and you will be in business.

Leave old versions of SAISGn's (where the n's differ) around, so that
old  .SAV  files  will still work.   In general, you should save core
images BEFORE running them  the  first  time.   Otherwise,  you  will
probably  save  your own copy of the segment and stuff like that.  It
is not really a problem here, because our system's  different;  so  I
don't really know what problems you'll encounter.

Our  LOADER contains the /Y switch,  causing  SYS:SAILOW to be loaded
immediately after the /Y has been scanned. In addition, our CCL  will
look  for .SAI extensions on any of its inputs, and will put out a /Y
first thing (even before /D if debugging, etc.) if it sees  any.   In
the near future, we will probably remove the /Y business, and let CCL
insert the SYS:SAILOW directly-- under a previous,  more  complicated
scheme, the /Y stuff made more sense.

That  should  do  it.  The LOWER, UPPER, and TAILOR .REL files can be
deleted as soon as SAILOW and SAISGn  have  been  made  --  they  are
purely intermediate entities.
APPENDIX I -- SAILMAKER's CHECKLIST

A. Getting files from MTA
 ( )1. Use FAILSAFE.

B. Getting a SAIL system up
 ( )1. Load the SAIL.REL,/BDDT.REL,/LLIBSAn provided with our LOADER
 	or with any version 54 or later LOADER with FAILSW and SAILSW
	turned on.
 ( )2. Save as SAIL.SAV or something in a convenient place.
 ( )3. Transfer LIBSAn.REL, 2OPS2.OPS, PROCES.DEF, and BKTBL.BKT to SYS -- 
	also SAIL, and/or FAIL, and/or LOADER, and/or DDT, if desired.

C. Changing the productions (HEL) or built-in descriptions (FOO2)
 ( )1. Make the appropriate edits
 ( )2. Compile PTRAN.SAI, RTRAN.SAI (require SCNCMD,WNTSLS as source
					files)
 ( )3. Load and run PTRAN (formerly HYRS).
        Command string is PROD←HEL<cr>.
 ( )4. Load and run RTRAN (formerly HYSS). 
	Command string is RESTAB←PROD,FOO2<cr>.
    5. Do one of parts D, E, F, or G.

D. Assembling Two-segment, no debugging compiler
 ( )1. Assemble with FAIL:
    SAIL←HEAD,SAIL,PARSE,HEL,FOO2,PROD,RESTAB,SYM,GEN,ARRAY,EXPRS,
	STATS,LEAP,TOTAL,PROCSS,COMSER
    2. Load SAILOW,SAIL without DDT.
 
E. Assembling Two-segment, debugging compiler
 ( )1. Change FTDEBUG in SAIL to 1, or insert a file ahead of SAIL
 	in the command string  below (DB, say), with FTDEBUG a 1.
 ( )2. Assemble with FAIL:
   SAIL←HEAD,DB,SAIL,....
    3. Load as in part D with DDT

F. Assembling a One-segment, no debugging compiler
 ( )1. Assemble as in part D
    2. Load as in part B without DDT

G. Assembling a One-segment, debugging compiler
    1. Guess.


H. Assembling a great big RUNTIM.REL
 ( )1. Assemble with FAIL:
  RUNTIM←HEAD,GOGOL,STRSER,IOSER,ARYSER,NWORLD,LEPRUN,WRDGET
    2. Load SAIL programs with RUNTIM.

I. Creating a standard LIBSAn.REL
 ( )1. Compile and load SCISS.SAI
 ( )2. Save as SCISS.SAV
 ( )4. Run SCISS.  Reply Y<cr> to all questions.
 ( )5. After much typeout, it should report that LIBSAn.REL exists
       so put it where you like, preferably on SYS.
 ( )6. {REENT}For creation of HLBSAn  see Appendix VI
    7. If you get in trouble, Appendix VI may provide some shortcuts
       for getting out of it.

J. Creating shared segments
 ( )1. Modify FILSPC to taste
 ( )2. Assemble LOWER←HEAD,FILSPC,LOW,GOGOL,STRSER,IOSER,ARYSER,NWORLD
 ( )3. Assemble TAILOR←HEAD,FILSPC,TAILOR
 ( )4. Assemble UPPER←HEAD,UP,GOGOL,STRSER,IOSER,ARYSER,
						NWORLD,LEPRUN,WRDGET
 ( )5. Load TAILOR and UPPER with a SAIL-compatible LOADER
 ( )6. Run result, getting SAILOW.REL and SAISGn.SHR
 ( )7. Transfer SAILOW to SYS, SAISGn.SHR to wherever FILSPC says.

K. Running with shared segments
 ( )1. Load SAILOW.REL FIRST!!!!!
 ( )2. Load DDT and programs
 ( )3. Start job -- segment will hook up right away.

L. {REENT} Running with 2-segment programs (/H when compiling)
 ( )1. Compile with /H in command string
 ( )2. Load as usual (DO NOT LOAD SAILOW AT ALL)
    3. The HLBSAn library will provide al(most al)l high-segment
	routines.
APPENDIX II -- FILE DESCRIPTIONS

A. SAIL COMPILER:

HEAD
-- a definition file, defines useful macros, accumulators etc.  There
are also definitions for the "user table", the table  of  good  stuff
which  contains  the  non-reentrant  information  for  use by runtime
routines.

SAIL
--  initializer  for  the compiler, command line scanner.  Almost all
the CCL code is in here.

PARSE
-- The syntax interpreter, the debugging routines (for looking at the
parse stack, symbol table entries, etc.)

HEL
--  This  is the file which contains the "english" of the productions
for SAIL.  It is included in the SAIL  assembly  as  a  comment.  The
actual production  interpreter  tables  are  generated from it by the
program PTRAN, which uses this file (HEL) as source, and  dumps  its
output into PROD.

FOO2
-- Again included  in  the  assembly  as  a  comment.   This  is  the
"english" specification of the pre-defined procedures.  These are all
the procedures available at runtime.

PROD
-- Syntax tables, generated by PTRAN.

RESTAB
--  Reserved  word tables and pre-defined procedure tables, generated
by the program RTRAN, with FOO2 and PROD as input.

SYM
--  This is the scanner.  This has the code for inputting from source
files, producing a listing, expanding  macros,  looking  up  symbols,
entering symbols, and delivering and reclaiming symbol table blocks.

GEN
-- This is the first part  of  the  generators.   Contains  code  for
initialization,  declarations,  storage allocation in object program,
inline code, syntax error messages, etc.

ARRAY
-- Contains generators for array references.

EXPRS
--   Generators  for  expressions  --  arithmetic,  string,  boolean,
assignment statements.

STATS
--    Generators   for   statements:   LOOP   constructs,   procedure
declarations, etc.

LEAP
-- Generators for LEAP, backtracking and procedure items.

PROCSS 
-- Generators  for process,coroutine, event constructs.

TOTAL
--  This  file  contains  the  generator  subroutines  used  for type
conversion,  accumulator  management,  binary  file  output,   symbol
output, and miscellaneous other things.

COMSER
-- Random service routines for the compiler (e.g. some string garbage
collector goodies).


SAIL RUNTIME:

GOGOL
-- Contains most of  the  runtime  environment  stuff  (also  compile
time).  Core  allocation,  UUO  handler,  string  garbage  collector,
allocation (i.e. of stacks, string space) stuff.

STRSER
--   Contains   most   of   the  string  handling  routines  such  as
concatenation, substring, etc.

IOSER
--  Contains  runtime routines for doing I/O a few other things.

ARYSER
-- Contains runtime routines for doing array allocation & deallocation,
run time "go to solving", and the apply construct.

NWORLD
--  Contains runtime routines for process handling

LEPRUN
-- Runtime routines for LEAP.

WRDGET
-- Contains one-word,two-word and string descriptor  providers, as well
   as REMEMBER, FORGET and RESTORE routines.

UP, LOW, TAILOR, FILSPC
-- Files used for making shareable runtime routines.


SAIL SERVICE:

PTRAN.SAI
-- SAIL program for compiling syntax tables (see description below).

RTRAN.SAI
-- SAIL program for compiling tables for  reserved  word  definitions
and pre-declared procedure definitions.

SCNCMD,WNTSLS
-- SAIL sourcefiles required by PTRAN and RTRAN.

MAKTAB.SAI
-- SAIL program to write the file 2OPS2.OPS, which  contains  op-code
definitions for the inline code generators (START_CODE).


NON-TEXT FILES -- TO HELP YOU GET SAIL UP FAST:

SAIL.REL
-- An assembled version of SAIL, with FTDEBUG set (i.e. you must load
it with DDT).  If you are able to assemble your own .REL of SAIL, you
can save considerable space by turning FTDEBUG off.

LIBSAn.REL
-- A good library file.

BKTBL.BKT
-- The specification file for the STDBRK function.

2OPS2.OPS
-- The inline code opcode table.  Make a new one with MAKTAB.SAI.

PROCES.DEF
-- A set of useful macros which a multiple process programmer may
require as a source file.

OTHER SYSTEM PROGRAMS:

FAIL and FAIL.REL
-- This is the assembler which will assemble all of the SAIL compiler
and runtime text files mentioned above. There  may  be  some  trouble
getting  this  to  run  on your system. If so, I suggest loading FAIL
with our DDT and looking around. Common problems are with the  APRENB
code.   FAIL asks for interrupts on ILL MEM REF so that it can assign
more core, link up free storage, etc.  If you  get  an  ILL  MEM  REF
message  on  your  console  while  running  FAIL, something is wrong:
either your system (this has been known to  happen  with  APRENB)  or
FAIL (there is a rumor that APRENB must be called after each trap).

LOADER
-- This  loader is set up for SAIL, and contains the /Y (two segment,
see above) option.  It  can  be loaded by almost any previous loader.
If you have V52 or later, and don't need /Y, just use your own  (con-
figured for SAIL and FAIL, of course (of course!). Our  LOADER is set
up  also to provide the /B and /K features automatically, the desired
state for programs with SAIL stuff in them.

DDT and DDT.REL
-- This is an improved DDT, and you might as well put it up  on  your
system.  There are many new features (see description below).

CREF.MAC
-- This is the cross-reference program which works for FAIL and SAIL.
(There  are  bugs  in the SAIL compiler output of CREF information --
wrong block names sometimes happen -- we will fix it sometime, but it
didn't seem like the most important thing in the world, also conditional
compilation is known to put out incorrect listing files).


SCISS.SAI
-- This  program creates the LIBSAn and HLBSAn libraries, as described
in  varying degrees of detail in other parts of this document.

PROFIL.SAI
-- This program is applied to a SAIL listing file (with /K option) and
a  .KNT  file  created  by  a  program which was compiled using /K, as
described in the SAIL manual, to create a "program profile" listing.

FAIL.ON, SAIL.DOC
The complete FAIL manual, and the
complete SAIL manual -- of little use to you if you don't have a lower-
case printer, probably.  They're big, so keep them off the disk unless
you have plenty of room.

OTHERS
These are stored after the EOT marks on the tape.  The section on getting
started describes how to get them off.  Take a look at them if you like
and decide whether they might be useful to you.  Otherwise forget them.
APPENDIX III -- REFERENCES TO OTHER USEFUL DOCUMENTATION

A. See HEAD for complete description of conditional assembly
   switches, the macros which simplify their use, and the files
   in which they are defined.

B. See SAIL for a complete listing of FAIL commands for creating
   various kinds of compilers (slightly invalid for non-Stanford
   systems).

C. See GOGOL for a complete listing of FAIL commands for creating
   various kinds of runtime routines, libraries, etc. -- also for
   the COMPIL, ENDCOM, and ORDER constructs used by SCISS -- lastly
   for the usage of the HERE macro to conveniently create the upper
   segment transfer vector (HERE may be defined in HEAD).

D. See PARSE for a complete description of the features of the 
   debugging versions of the compiler -- features generally useful
   only to the maintainers of SAIL.

E. See NEWMAN for recent changes to the language.

APPENDIX IV -- THE PARSE TABLES (HEL) AND PRODUCTION COMPILER (PTRAN)

The program  PTRAN   expects   an   input  file  of  a  very  special
format.  The ultimate aim of this input file is to specify a sequence
of productions, but we must first specify  the  production  alphabet,
both terminal and non-terminal.

The  meta  language for specifying productions consumes a few symbols
and conventions.  First, all alphabetic characters in the input  file
must be in upper case.  The only delimiters are space and tab, so →AG
does NOT get interpreted as two separate symbols.

1.  	For  various  undisclosed  reasons,  we  must  first  provide
alternate "names" for all single-letter delimiters we may need,  such
as  (  ) } ↑ [ ], etc.  The pseudo-op <SYMBOLS> is given, followed by
pairs of

	single-letter-delimiter crazy-alternate-name

See the example below for some  instances  of  this  phenomenon.  The
crazier  the  name  the  better.   This is so that the symbols can be
included in the  scanner  table.  Note  the  interaction  with  these
aliases and the reserved word scheme. Thus ≡ which is the same as EQV
is equivalenced by this scheme.

2. 	The terminal symbols of the language are then specfied in two
groups:  first, those which the scanner  knows  about  directly,  and
second,  the group of reserved words in the language (these look like
identifiers to the  scanner,  but  you  obviously  desire  a  special
interpretation).  The  first  group  is  initiated with the pseudo-op
<TERMINALS>, and must include all the single-letter-delimiters  cited
in 1 which do not have reserved word equivalents. The second group is
started with <RESERVED-WORDS>, and  is  merely  a  list  of  all  the
reserved words you desire.

3.	The non-terminal symbols are then declared.  These are things
which you may want to put on the  stack  as  "markers"  of  partially
completed   reductions.    The  pseudo-op  <NON-TERMINAL-SYMBOLS>  is
followed by a list of such symbols.

4.	For efficiency reasons, it is helpful to  define  CLASSES  of
symbols.  Then with one production, we can determine if a whole class
of productions are applicable, and we can often avoid stating all the
productions.   To  specify  classes,  we  start  with  the  pseudo-op
<CLASSES>, and then, on a one-class-to-a-line basis, we specify:

	class-name	class-element class-element ....

where class-name must begin with a @. All of the class-elements  must
have already been  defined  in  2  or 3 above or a previously defined
class-name. Note that two classes are predeclared. These are RESERVED 
which contains all the reserved words and TERMINAL which contains all
the terminal symbols.  

5.	Finally we are ready to state the productions.  We  give  the
pseudo-op  <PRODUCTIONS>  to  start  this off.  The name of the first
production is  BB0  (this  may be changed by altering the contents of
the cell PRODGO in file PARSE).

The  interpreter  will  start  AFTER ONE SCAN, so that the top of the
stack will already have the first "parse token" on it.

The syntax of each production is:

label:	LHS →→ RHS EXEC xxx SCAN α ¬yyy #zzz ↓↓ ↑www

This specifies a  production.   These  symbols  need  at  least  some
explanation:
-- the label is the production "name". It is optional.  All labels in
        the program must be unique in their first 6 characters. There
	may not be a space between the label and the :.
	(If you plan to use the debugger (FTDEBUG← 1) it is advisable
	 to  have  only  3  character  label  names to avoid spurious
	 production breaks).

-- LHS is a left-hand-side-list.  That is, a list of symbols declared
        in 2,3, or 4 above which is to be matched against the current
        top elements of the stack.

--  RHS is a right-hand-side-list.  This is the list of symbols which
        will replace the LHS on the stack if the production succeeds.

--  EXEC  specifies  that a list of execs is to be called.  The names
        you give in this list of exec  routines  should be  the names
        of the procedures that you make up in your exec routine file.

-- SCAN specifies that we are to scan before going  on  to  the  next
        production.

--  the  # ¬ ↑ and ↓↓ parts specify where "control" of the production
        interpreter is to go.

The following things are omittable:

-- the label

-- the →→ and right-hand-side-list, in which case it is assumed  that
        if  the  production  succeeds,  the  stack is restored to its
        original condition.

-- the right-hand-side-list, in which case nothing is restored to the
        stack.

-- EXEC and the list of exec routines which follows it.

--  SCAN  if  you do not want to scan.  Note that SCAN α means scan α
        times before going to the success spot.

-- the #zzz, ↓↓, and/or ↑www may be omitted.

Now for the interpretation.  When the interpreter is pointed at this
production, the stack is compared  against  the  left-hand-side-list.
The  last element in this list is compared against the current top of
the stack, and so on back the list and up the  stack.   Compares  are
equal if:

-- the symbols actually match.

-- the list element in the left-hand-side is  SG,  which  stands  for
        sigma, and compares equal to anything.  SG  is  thus  a  meta
        symbol of the production compiler, and may not be used in any
        other way. In fact, any identifier beginning  with  SG  is  a
        "sigma".   For  the purposes of stack restoring, however, SG1
        matches only SG1, etc.

--  the  list element in the left-hand-side is a class symbol and the
        corresponding stack element belongs to  that  class.  If  the
        left-hand-side-list  fails  to match the top positions of the
        stack, the production interpreter sees a failure and goes  to
        another  production.  The next production is normally the one
        following the one which failed.  If you want to specify  some
        other  failure  production, the #zzz construct is used, where
        zzz is the label of the production you want to go to.

If the left-hand-side-list matches the top of the stack, then:

1. These stack elements are popped off the stack temporarily.

2. If any exec routines have been specified, these  are  called.  The
        statement  EXEC FOOBAZ causes the subroutine called FOOBAZ to
        be  called.   The  statement  EXEC  @DCL  FOOBAZ  causes  the
        following  to happen: FOOBAZ is a routine which wants to know
        some  class  information  about  one  of  the  left-hand-side
        elements.   This  element  is specified by the @DCL (this was
        the same thing that occurred on the left-hand-side). Just how
        this  class information is passed is not important here. Upon
        return from all exec routines, we continue to:

3. The stack is  then  fixed  back  up,  reflecting  any  changes  as
        specified in the right-hand-side-list.

4. The scanner is called if SCAN was specified.

5.  The  production has now "succeeded".  We must cast around for the
        next   production.    Each   production   must   have    some
        specification  of  what  to  do  on  success.   If  you  only
        specified a ¬yyy , then we do a "jump" to the production with
        label yyy. If you specified a ↑aaa and a ¬yyy , we do a "push
        jump"  to  production  aaa.   When  we   return   from   that
        "subroutine,"  we  will go to production yyy.  The "pop jump"
        is specified by ↓↓.  It makes no sense to say: ¬aaa ↓↓  since
        these  two  operations  conflict  (in fact, the pop jump will
        take precedence).

6.  An  extension  has been made to production language to enable the 
implementation  of conditional compilation in SAIL.  This consists of 
maintaining  two  parser stacks.  When certain reserved words such as
IFC  are seen a "push jump" is done to a production which is accessed
by  an  index  to a table via the left hand entry of the words symbol
table  semantic  entry.  Parsing  then  continues in a coroutine-like
manner. The  PRESUME  construct has been added to production language
to  facilitate  a change in the current parser stack from conditional
compilation  to  SAIL-like  compilation.  Coroutine-like parser stack
switches  from  SAIL  to conditional compilation is done when certain
reserved  words  are  seen  such  as ELSEC.  A PRESUME followed by ↓↓
indicates that the conditional compilation process is finished.  Also
note  that  when DEFINE is seen, it is treated in the same way as IFC
with  the  exception  that  there is no need for an additional stack.  
If  you  do  not  understand  all  this  don't worry, you are in good 
company.

The list of productions must be followed by the pseudo-op <END>

There  is  a  facility  for  passing  class-type  information to exec
routines.   The SAIL  production  interpreter  stores  a  number   in
accumulator  number  2  before executing  the   exec routine that you
specified. This number contains the type  information you  need.  The
problem   of   interpreting   that  number  is  complicated  but  not
impossible.  The  elementary  statement  is:  the number is the index
(starting  at 0) into the line of symbols in which that class type is
declared. So if you declare the class type

	@DCL INTEGER REAL BOOLEAN COMPLEX STRING

and if you wrote a production

%CON:	@DCL IDENT , →→ @DCL	EXEC @DCL ENTID SCAN 2	¬%CON

then when ENTID is called, AC 2  will contain the following numbers:

	parse token which compared
	equal to @DCL
	INTEGER					0
	REAL					1
	BOOLEAN					2
	COMPLEX					3
	STRING					4

This simple explanation breaks down when, say BOOLEAN was declared to
be a member of another class, and THAT CLASS WAS DECLARED BEFORE @DCL
WAS.  So the easy rule is: declare the classes that will be  required
to  provide  class  information  to semantic routines first, and then
those classes which are used only for parsing purposes.

Numerical parameters can also be passed to exec routines.  This is 
done in the same manner as parsing class-type information.  The only 
difference being that the @ symbol is followed by an integer instead 
of a class name.  

III.  Pre-loaded symbol table input format (program RTRAN).

This file obeys many of the same conventions  as HEL  (no lower case,
delimiters  are  only  space and  tab,  comment  operator is  MUMBLE,
etc.). Don't  play with  <ASSIGN> or  <DEFINITIONS>  unless you  have
become a real wizard.  There isn't much content there anyway.

The functions  are all listed with  their parameter types.   There is
no  special  order, except  that the  first  function is  the default
program block.   Hence,  the default  program  name is  M. I  suggest
leaving this as is.

A function description  is: (1) the first line  has the function name
(this is  what will  go out  to the  loader as  an external  request)
followed by the value  that the function returns. UNTYPE  means it is
a  procedure and  not a  function (other types  are specified  by the
names  of  the  semantic  bits  for  them)  followed  by   some  bits
specifying to  the compiler how to  interpret the rest of  the symbol
table  entry. OWN absolutely  MUST be cited.   Reserved-functions are
stored in  a compact  way,  and  OWN specifes  this special  packing.
BILTIN is  specified if the  function will save  accumulators (except
the result  ac  if  any) over  the  function  call.   Most  of  these
routines  do save  accumulators,  but for  a  special case,  consider
INPUT.   The integers BREAK and  EOF referred to in  the call on OPEN
to open the channel may be changed by a call to INPUT.  If  copies of
these integers were thought by the compiler  to be in the ac's at the
time, disaster  would (and did!) strike.  The last thing on the first
line is the number of parameters to the procedure.  Then (2) come the
parameters, one  to a line.   There are four elements  to a parameter
description: (1) a "type"  of the parameter,   an artifact left  over
from  an earlier  scheme,  and  ignored  by RTRAN,  (2)  an  optional
comment  about what  the parameter is  -- must  be a single  word (no
spaces or tabs)  surrounded by ( ).   Then (3,4)  come the right  and
left halves  of the semantic word  to specify what type  of parameter
we  have. Things  here are pretty  obvious except  for one particular
feature -- reference parameters may have many types.   If the routine
really  only needs an  address (ARRTRAN,ARRBLT,  etc.) we  don't care
what type (INTEGER,REAL, etc)  the parameter had.   So in this  case,
the actual-formal match  is made with  the condition: "any  bit which
is  on in the actual  must be on  in the description  of the formal,"
with the exception that  if one is an  array (SBSCRP) they both  must
be.   There is one  other feature that  may be useful.   If a  "$" is
placed  before field  (3), then the  parameter may  be "defaulted" to
its null value (ie integers to zero, itemvars to  BINDIT, etc) if the
actual call omits  this actual parameter. Such defaultable parameters
must come  at  the  end  of  the argument  list  and  must  be  value
parameters.  
APPENDIX V -- DDT AND OTHER MODIFIED DEC SOFTWARE

A. DDT

To  name  the  program,  type name$:  ($ stands for altmode).  To get
inside a "block", type blockname$& .  If you want to name a symbol in
another block without permanently entering that block (as above) type
block&symbol .


The following changes have been made to DDT:

1.   Halfword  printout  is  now  of  the  form A,,B instead of (A)B.
Either form may be used  on  input.   The  difference  is  that  A,,B
truncates A to 18 bits before swapping halves while (A)B does not.

2.  $U is a new output mode.  It is the same as $A$H.

3.   $F  mode  will  now  print normalized floating permit numbers as
decimal integers.  This means that FORTRAN users may, in general, use
$F to look at all variables and they will be printed correctly either
fixed or floating.

4.  If the address of a string of ASCIZ text is placed in $nB+3, then
whenever  breakpoint  n is reached, DDT will act as if the characters
in the string  were  being  read  from  the  teletype.   If  you  are
preparing  such a string in advance use either $ or ≠ (≠33 octal) for
altmode.

5.   If a bytepointer to an asciz string is placed in $M-l, DDT  will
act  as  if  the  characters  in  the  string are being read from the
teletype.

6.  $$7" <delimiter> characters <delimiter> will  act  just  like  an
asciz  statement  in  MACRO  or FAIL,i.e., more than one word will be
filled with asciz for the characters if necessary.  $$" will  have  a
similar effect but with sixbit.

7.   Typing  <number>$$P  will  cause  DDT to do an automatic proceed
<number> times instead of forever.

8.  When printing in $$S mode, no word will be printed out as  an I/O
instruction  (CONO, DATAO, CONI, etc.) unless the device number is in
a special table.  The table is 10 words long and is  in  $I-1,  $I-2,
etc.  Simply  put  device  number  here  to  have the appropriate I/O
instructions printed.

9.  If an address is placed in  $M-2  then  for  each  character  DDT
wishes  to  output,  a  pushj  1,@$M-2 will be executed.  This allows
output to be redirected to some  device  other  than  the  TTY.   The
character is in register 5.  The routine should preserve all AC's and
end with a POPJ l,.

10.  In byte mode output ($<number>0), if a size of 0  is  specified,
DDT will use a special mark in $M+2. The boundry between 1 and 0 bits
specifies the size of the bytes.  For example, a word containing

	11111111111 00000000000 11100010110001

would print 2 . 11 bit bytes, 2 3 bit bytes, 2 1 bit bytes, a  2  bit
bytes, a 3 bit byte, and a 1 bit byte.

11.   Bytes may be input of $<number>%.  This should be followed by a

by an altmode.  If number of bytes in a word is not integral the last
byte is treated as if the word were larger (bit number  greater  than
35).   This makes input compatible with output.  A size of O uses the
mark in $M+2 as above.

12.  It is now possible to print flag words and  T type  instructions
(TRNN, TLNN, etc.) with suitable names for the bit involved.  In $M+3
a pointer of the following form is placed:

			T0:	-------------
				|            |
     -------------  		|            |
$M+3 |  L1 | T0  |		| Table 0    | 
     -------------  		|            |
				-------------

			
L1:  L2,,T1			-------------
				|            |
				| Table 1    |
				|            |
				-------------

L2:  0,,T2			-------------
				|	     |                
				| Table 2    |
				|	     |                
				-------------

As  many  tables as desired may be included.  The pointer to the last
table should have 0 in the left half. Each table contains  36  words.
The  nth word contains the RADIX50 for the name of bit n.  $<number>J
mode will cause a word to be printed out using the bit names in table
number.   If  an  entry  for  a  bit  is 0, the numeric value will be
printed.  A typical word might look like

foo! baz! 123,, fool! garp! 2

$J means $0J.  $nL causes the left half to be printed in symbolic and
the  right  half  to be printed in this bit mode, using the left-half
bits.  This is for printing out the instructions  like  TLNN,TLO,TLZ,
etc.   The corresponding command for TRNN,TRO,TRZ etc is $V. Needless
to say, the instructions do not have to be TRNN, TLNN etc.,  but  may
be anything.
APPENDIX VI -- ADDITIONAL SUPPORT SOFTWARE -- SCISS, MAKTAB

A. SCISS

This description attempts to  give  a  complete  description  of  the
possible  modes  of  operation  of  SCISS.   It  answers the pressing
question: What happens if I reply  NO  to  the  "STANDARD?  "  query.
Here's what happens --

1. The file ORDER consists of a comment (thus ignored by FAIL) of the
form:
	COMMENT ⊗
	NAM,5
	ALL,HEAD,!GOGOL
	HDR, GOGOL
	LOR,LUP,KNT...
	...
	⊗ 
SCISS   reads  it  to  find  the  version  number  of   the   library
(the digit following "NAM," and the  list  of  all  possible  library
entries.   It  creates  files  of  the form SAILOR, SAISGC, .... when
operating.   The  SAILOR...  form  is  the  one  you  should  use  in
communicating with SCISS.

NOTE:  if  you  change  the version number of the library, be sure to
also change the library names  accordingly  in  FILSPC  so  that  the
compiler will generate library request for the current version of the
library.

2. The COMPIL macro has as arguments, among others, the name  of  the
individual  entry  (3  letters,  like LOR), the list of ENTRIES to be
issued when in LIBRARY  mode,  any  EXTERNALS  and  INTERNALS  to  be
issued, and a short description.  When not in library mode,this macro
simply issues the ENTRY and INTERNAL lists as INTERNALS,  and  issues
the EXTERNALS.  When SCISS encounters it, it compares the name of the
entry with the list of those selected to be assembled this  run.   If
the  name matches an entry, it writes a file SAIccc.FAI, with all the
code between the COMPIL and the matching  ENDCOM  (which  expands  in
this  case  to  END)  in  it.   COMPIL  in this mode will expand when
assembled into the appropriate ENTRYs, TITLEs,  etc.     Notice  that
there is a COMPIL macro for each possible library entry, and an entry
in the ORDER list for every instance of COMPIL.   Thus  the  standard
case,  which  uses  the  whole ORDER list, makes the largest possible
library.

3. SCISS will ask the question "STANDARD?" before PASS 1  and  before
PASS2  (unless  PASS  1  was totally suppressed). To get the standard
LIBSAn simply reply Y<cr> to both questions. Otherwise type N<cr> and
then you will get a list of options.

PASS 1

	1 PASS 2 NOW
	2 DON'T CHAIN TO FAIL
	3 DON'T CREATE INTERMEDIATE FILES
	4 MAKE REENTRANT LIBRARY
	5 SELECT ENTRIES FROM PROMPT-LIST
	6 SPECIFY ENTRIES EXPLICITLY
	7 DON'T DELETE INTERMEDIATE FILES (PASS 2)
	8 DON'T MAKE A LIBRARY(PASS 2)

Type the indices of those options you wish to invoke:

1. PASS 2 NOW means don't create the SAIxxx.FAI files or  call  FAIL.
This makes sense only if SCISS has been run before and the SAIxxx.REL
files still exist. This option will cause the  copying  of  the  .REL
files  (which  ones,  may be specified by invoking options 5 or 6) to
form a library (unless inhibited by option 8) and then  deleting  the
.FAI  and .REL files (unless inhibited by option 7). The library will
be named HLBSAn if option 4 is requested (The .REL files should  have
been  created  by  running  SCISS  with a REENTRANT library requested
during the first pass).

2. DON'T CHAIN TO FAIL  means  just  create  the  .FAI  files.  Don't
assemble them.

3. DON'T CREATE INTERMEDIATE FILES.  Don't  create the .FAI files but
unless inhibited assemble the .FAI files generated previously.

4. MAKE REENTRANT LIBRARY means to make a HLBSAn instead of a LIBSAn.
	(command must be given to both PASS 1 and PASS 2)

5. SELECT ENTRIES FROM PROMPT-LIST  means  that  SCISS  will type the
library entries and let you indicate whether you desire that entry in
the  library.  This  option  and the next are very useful in avoiding
reassembling everything when an assembly error has occurred in one or
two library entries. SCISS will type the names of the library entries
like SAICOR, pausing for your response:
		Y<cr> retain this entry
		N<cr> omit this entry
		DONE  dispose  of  the rest of the entries as you did
			the last (all Y or N)

6.  SPECIFY  ENTRIES  EXPLICITLY  - type the names of the entries you
want (SAILOR etc) separated by <cr>. After all  the  names  you  want
type DONE<cr>

7.  DON'T  DELETE  INTERMEDIATE  FILES- don't delete the .FAI or .REL
files (only meaningful if doing PASS 2 now)

8. DON'T MAKE LIBRARY.(only meaningful doing PASS 2 now).

PASS 2

An important thing to remember is that SCISS  doesn't  remember  what
you  requested  at  the  beginning of PASS 1 so if you want something
unusual (e.g. a  reentrant  library  or  a  library  without  certain
entries) you are going to have to tell SCISS again.

	1 DON'T DELETE INTERMEDIATE FILES
	2 DON'T MAKE A LIBRARY
	3 MAKE A REENTRANT LIBRARY
	4 SELECT ENTRIES FROM PROMPT-LIST
	5 SPECIFY ENTRIES EXPLICITLY

These have the same meaning as they did in PASS 1.

				GOOD LUCK WITH SCISS

B. MAKTAB.SAI

Assemble  and  run  to  get  a new copy of 2OPS2.OPS, just for fun or
because you changed it.   This file  is  needed  on  SYS  before  the
START_CODE feature will work.